<?php

/**
 * 支付宝支付
 * File Name：alipay.php
 * File Encoding：UTF-8
 * File New Time：2014-6-4 9:51:54
 * Author：水平凡
 * Mailbox：admin@abc3210.com
 */
class Alipay {

    //支付宝配置
    private $config = array();
    //错误信息
    private $error = NULL;
    //订单信息
    private $data = array();


    public function __construct() {
        $this->config = require dirname(__FILE__) . '/alipay.config.php';
    }

    /**
     * 获取错误信息
     * @return string
     */
    public function getError() {
        return $this->error;
    }

    /**
     * 设置订单数据
     * @param type $data
     * @return \Alipay
     */
    public function data($data = '') {
        if ('' == $data && !empty($this->data)) {
            return $this->data;
        } else {
            $this->data = $data;
        }
        return $this;
    }

    /**
     * 跳转到支付宝支付页面
     * $Jump 是否是马上要跳转，默认不是
     * 返回一个链接
     * @param type $ordersId
     * @return boolean
     */
    public function payment($Jump = false) {

        if (empty($this->data['OrdersnID']) || !($model = OrdersnModel::model()->findByPk($this->data['OrdersnID']))) {
            $this->error = '该订单不存在！';
            return false;
        }else{
            $this->data = $model->attributes;
        }
        //设置域名
        // Yii::app()->getRequest()->setBaseUrl(ConfigModel::model()->getConfig('siteurl'));
        Yii::app()->getRequest()->setBaseUrl(Yii::app()->request->hostInfo);
        $parameter = array(
            "service" => "create_direct_pay_by_user",
            "partner" => trim($this->config['partner']),
            "payment_type" => '1',
            "notify_url" => YzwController::U('front/alipay/notify'),
            "return_url" => YzwController::U('front/alipay/return'),
            "seller_email" => $this->config['seller_email'],
            "out_trade_no" => $this->data['OrderNo'],
            "subject" => empty($this->data['OrderTitle']) ? '妈咪街充值' : $this->data['OrderTitle'], //订单名称
            "total_fee" => $this->data['Money'],
            "body" => '', //订单描述
            "show_url" => '', //商品展示地址
            "anti_phishing_key" => '', //防钓鱼时间戳
            "exter_invoke_ip" => '', //客户端的IP地址
            "_input_charset" => trim(strtolower($this->config['input_charset'])),
        );
        if ($Jump == false) {
            //建立请求
            $alipaySubmit = new AlipaySubmit($this->config);
            $html_text = $alipaySubmit->buildRequestForm($parameter, 'get', '请稍候...');
            header("Content-type:text/html;charset=utf-8");
            echo $html_text;
            exit;
        } else {
            //建立请求
            $alipaySubmit = new AlipaySubmit($this->config);
            //待请求参数数组
            $para = $alipaySubmit->buildRequestPara($parameter);
            $url = $alipaySubmit->alipay_gateway_new . "_input_charset=" . trim(strtolower($alipaySubmit->alipay_config['input_charset']));
            while (list ($key, $val) = each($para)) {
                $url.= "&{$key}={$val}";
            }
            return $url;
        }
    }

    /**
     * 创建订单信息
     * @param type $orders 订单基本信息
     * @return boolean
     */
    public function createOrders($data = array()) {
        if (!empty($data)) {
            $this->data = CMap::mergeArray($this->data, $data);
        }
        //没有指定订单号则自己创建
        if (!isset($this->data['OrderNo'])) {
            $this->data['OrderNo'] = $this->generateOrdersNumber();
        }
        if (!isset($this->data['UserID'])) {
            $this->data['UserID'] = Yii::app()->user->id;
        }
        $model = OrdersnModel::model();
        $model->setIsNewRecord(true);  
        $model->attributes = $this->data; 
        if($model->save()){
            $this->data = $model->attributes;
            return true;
        }else{
            $error = $model->getOneError();
            $this->error = $error ? $error : '订单创建失败，请重新提交！';
            return false;            
        }
    }

    /**
     * 生成一个订单号
     * @return string 订单号
     */
    public function generateOrdersNumber() {
        mt_srand((double) microtime() * 1000000);
        $OrderNo = date('Ymd') . str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT);
        if ($this->isOrdersNumberRepeat($OrderNo)) {
            //再次调用重新生成
            return $this->generateOrdersNumber();
        }
        return $OrderNo;
    }

    /**
     * 检查订单号是否重复
     * @param type $OrderNo 订单号
     * @return boolean true重复
     */
    public function isOrdersNumberRepeat($OrderNo) {
        $count = OrdersnModel::model()->find(BaseModel::getC(array('OrderNo' => $OrderNo)));
        return $count ? true : false;
    }

    /**
     * 支付宝异步通知处理
     */
    public function alipayNotify() {
        $alipayNotify = new AlipayNotify($this->config);
        $verify_result = $alipayNotify->verifyNotify();
        if ($verify_result) {//验证成功
            //商户订单号
            $out_trade_no = $_POST['out_trade_no'];
            //支付宝交易号
            $trade_no = $_POST['trade_no'];
            //交易状态
            $trade_status = $_POST['trade_status'];
            if ($_POST['trade_status'] == 'TRADE_FINISHED') {
                //判断该笔订单是否在商户网站中已经做过处理
                //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                //如果有做过处理，不执行商户的业务程序
                //注意：
                //该种交易状态只在两种情况下出现
                //1、开通了普通即时到账，买家付款成功后。
                //2、开通了高级即时到账，从该笔交易成功时间算起，过了签约时的可退款时限（如：三个月以内可退款、一年以内可退款等）后。
                //调试用，写文本函数记录程序运行情况是否正常
                //logResult("这里写入想要调试的代码变量值，或其他运行的结果记录");
            } else if ($_POST['trade_status'] == 'TRADE_SUCCESS') {
                //判断该笔订单是否在商户网站中已经做过处理
                //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                //如果有做过处理，不执行商户的业务程序
                //注意：
                //该种交易状态只在一种情况下出现——开通了高级即时到账，买家付款成功后。
                //调试用，写文本函数记录程序运行情况是否正常
                //logResult("这里写入想要调试的代码变量值，或其他运行的结果记录");
                $this->orderProcessing($out_trade_no, $trade_no);
            }
            //——请根据您的业务逻辑来编写程序（以上代码仅作参考）——
            exit('success');  //请不要修改或删除
        } else {
            exit('fail');
        }
    }

    /**
     * 支付宝回调处理
     * @return boolean
     */
    public function alipayReturn() {
        $alipayNotify = new AlipayNotify($this->config);
        $verify_result = $alipayNotify->verifyReturn();
        if ($verify_result) {//验证成功
            //商户订单号
            $out_trade_no = $_GET['out_trade_no'];
            //支付宝交易号
            $trade_no = $_GET['trade_no'];
            //交易状态
            $trade_status = $_GET['trade_status'];
            if ($_GET['trade_status'] == 'TRADE_FINISHED' || $_GET['trade_status'] == 'TRADE_SUCCESS') {
                //判断该笔订单是否在商户网站中已经做过处理
                //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                //如果有做过处理，不执行商户的业务程序
                $this->orderProcessing($out_trade_no, $trade_no);
                return true;
            }
            return false;
        } else {
            return false;
        }
    }

    /**
     * 支付宝支付完成后订单处理
     * @param type $out_trade_no 商户订单号
     * @param type $trade_no 支付宝交易号
     */
    private function orderProcessing($out_trade_no, $trade_no) {
        $key = 'Alipay_orderProcessing' . yii::app()->user->id;
        $arrCache = yii::app()->cache->get($key);
        if(empty($arrCache)){
            yii::app()->cache->set($key, 1, 60);
        }else{
            return false;
        }
        //根据订单号查询订单记录
        $orderInfo = OrdersnModel::model()->find(BaseModel::getC(array('OrderNo' => $orderInfo)));
        //检查订单记录是否存在，且没有处理过
        if (!empty($orderInfo) && $orderInfo->Status == 0) {
            $orderInfo->AlipayNo = $trade_no;
            $orderInfo->Status = 1;
            $orderInfo->save(false, array('AlipayNo', 'Status'));

            $userModel = MemberModel::model()->findByPk(yii::app()->user->id);
            $userModel->Money += $orderInfo->Money;
            $userModel->save(false,array('Money'));
        }
        yii::app()->cache->delete($key);
    }

}
